//
//  Person.m
//  JKRuntimeTest
//
//  Created by 王冲 on 2018/10/7.
//  Copyright © 2018年 JK科技有限公司. All rights reserved.
//

#import "Person.h"
#import <objc/runtime.h>
@implementation Person


#pragma mark 动态解析进行转换方法(类方法)
+ (BOOL)resolveClassMethod:(SEL)sel
{
    if (sel == @selector(classTest)) {
        // 第一个参数是object_getClass(self)
        //class_addMethod(object_getClass(self), sel, (IMP)c_other, "v16@0:8");
        // 获取其他方法
        Method method = class_getClassMethod(self, @selector(classOther));
        // 动态添加test方法的实现
        class_addMethod(object_getClass(self), sel,
                        method_getImplementation(method),
                        method_getTypeEncoding(method));
        
        // 返回YES代表有动态添加方法
        return YES;
    }
    return [super resolveClassMethod:sel];
}

#pragma mark 类方法的转换（类方法classTest找不到就转换classOther方法）
+(void)classOther{
    
    NSLog(@"类方法classTest找不到就转换classOther方法");
}

#pragma mark 第 3 种动态解析进行转换方法(对象方法)
/*
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    if (sel == @selector(test)) {
        // 动态添加test方法的实现
        class_addMethod(self, sel, (IMP)c_other, "v16@0:8");

        // 返回YES代表有动态添加方法
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}
*/

#pragma mark test找不到后动态转换c_other的方法()
void c_other(id self, SEL _cmd)
{
    NSLog(@"c_other - %@ - %@", self, NSStringFromSelector(_cmd));
}

#pragma mark 第 2 种动态解析进行转换方法(对象方法)-------易懂(推荐)---------
/*
+ (BOOL)resolveInstanceMethod:(SEL)sel{
    
    if(sel == @selector(test)){
        
        // 获取其他方法
        Method method = class_getInstanceMethod(self, @selector(other));
        
        // 动态添加test方法的实现
        class_addMethod(self, sel,
                                method_getImplementation(method),
                                method_getTypeEncoding(method));
        
        // 返回YES代表有动态添加方法
        return YES;
        
    }
    
    return [super resolveInstanceMethod:sel];
}
*/

#pragma mark test找不到后动态转换other的方法
-(void)other{
    
    NSLog(@"%s",__func__);
}

#pragma mark 第 1 种动态解析进行转换方法(对象方法)
//+ (BOOL)resolveInstanceMethod:(SEL)sel
//{
//    if (sel == @selector(test)) {
//        // 获取其他方法
//        struct method_t *method = (struct method_t *)class_getInstanceMethod(self, @selector(other));
//
//        // 动态添加test方法的实现
//        class_addMethod(self, sel, method->imp, method->types);
//
//        // 返回YES代表有动态添加方法
//        return YES;
//    }
//    return [super resolveInstanceMethod:sel];
//}

struct method_t {
    SEL sel;
    char *types;
    IMP imp;
};

@end
